package com.stm.bi.report;

import com.stm.base.api.AnnualPolicyGoalRemoteService;
import com.stm.base.dto.query.AnnualPolicyGoalTargetQry;
import com.stm.base.dto.vo.AnnualPolicyGoalSummaryVO;
import com.stm.base.dto.vo.AnnualPolicyGoalTargetVO;
import com.stm.base.dto.vo.AnnualPolicyGoalVO;
import com.stm.base.dto.vo.DictVO;
import com.stm.base.provider.DictionaryProvider;
import com.stm.bi.core.util.DateUtils;
import com.stm.bi.core.util.ETLUtils;
import com.stm.bi.enums.DateType;
import com.stm.bi.model.DatatablePage;
import com.stm.bi.model.RowData;
import com.stm.bi.model.Title;
import com.stm.framework.core.tookit.BeanToolkit;
import com.stm.framework.core.util.FileResourceLoader;
import com.stm.framework.core.util.StringUtil;
import com.stm.framework.dbcp.JdbcService;
import com.stm.framework.dto.Response;
import com.stm.bi.constant.PaisiConstants;
import com.stm.bi.dto.query.PolicyEvolveDatatableQuery;
import com.stm.bi.enums.PolicyEvolveType;
import com.stm.bi.enums.ProductTechnologyType;
import com.stm.saas.api.OrgConfigRemoteService;
import com.stm.saas.api.PolicyDetailRemoteService;
import com.stm.saas.dto.query.PolicyDetailListQry;
import com.stm.saas.dto.vo.OrgConfigVO;
import com.stm.saas.dto.vo.PolicyDetailVO;
import com.stm.ucenter.api.DeptRemoteService;
import com.stm.ucenter.dto.query.org.DeptTreeQry;
import com.stm.ucenter.dto.vo.TreeVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author zpy
 * @date 2025/8/28 9:09
 */
@Component
public class PolicyEvolveDatatableQueryExe extends AbsDatatableQueryExe<PolicyEvolveDatatableQuery, DatatablePage> {
    @Resource
    private JdbcService jdbcService;

    @Resource
    private DictionaryProvider dictionaryProvider;

    @Resource
    private PolicyDetailRemoteService policyDetailRemoteService;
    @Resource
    private DeptRemoteService deptRemoteService;
    @Resource
    private AnnualPolicyGoalRemoteService annualPolicyGoalRemoteService;
    @Resource
    private OrgConfigRemoteService orgConfigRemoteService;

    public static final String SPLIT_KEY = "#";
    public static final Long ADD_ID_NUM = 1000L;


    @Override
    public DatatablePage query(Long orgId, String orgNo, PolicyEvolveDatatableQuery query) {

        DatatablePage datatable = new DatatablePage();
        datatable.setSize(query.getPageSize());
        datatable.setCurrent(query.getPageNum());
        // 时间列表
        List<String> dates = DateUtils.getReportDateList(query.getStartDate(), query.getEndDate(), query.getDateType().getValue());

        // 经营过程推移字典
        List<DictVO> dictList = dictionaryProvider.selectList(PaisiConstants.POLICY_OBJECTIVE);

        DictVO dict = dictList.stream().filter(item -> item.getValue().equals(query.getType())).findFirst().orElse(null);
        if (dict == null) {
            return datatable;
        }

        // 获取目标配置
        Response<OrgConfigVO> orgConfigRes = orgConfigRemoteService.selectDetail();
        if (!orgConfigRes.isSuccess() || orgConfigRes.getData() == null) {
            return datatable;
        }
        OrgConfigVO orgConfig = orgConfigRes.getData();
        boolean showTarget = false;
        if (orgConfig.getEnabledPolicyTargets() == null || orgConfig.getEnabledPolicyTargets().contains(dict.getValue())) {
            showTarget = true;
        }

        // 获取左侧栏项目
        List<TreeVO> treeList = getRowInfoTrees(query.getPolicyId(), query.getType(), query.getObjective());
        int maxLevel = 1;
        for (TreeVO item: treeList){
            if (StringUtil.isNotEmpty(item.getExtId())) {
                int level = Integer.parseInt(item.getExtId());
                maxLevel = Math.max(level, maxLevel);
            }
        }
        // 三级之后不显示目标
        if (maxLevel >= 3) {
            showTarget = false;
        }

        if (StringUtil.isEmpty(query.getYear())) {
            query.setYear(query.getEndDate().substring(0, 4));
        }
        // 表头设置
        datatable.setTitles(getTitles(dates, query, dict, showTarget, query.getExportable()));

        if (StringUtil.isEmpty(treeList)) {
            return datatable;
        }

        // id列表
        List<Long> idList = treeList.stream().map(TreeVO::getId).toList();

        // 实绩查询
        List<Map> maps = getOriginalData(orgNo, query, dates, idList);

        // 新老顾客特殊查询
        List<RowData> totalRowData = new ArrayList<>();
        if (PolicyEvolveType.PRODUCT_FEATURE.getValue().equals(query.getType())) {
            List<Map> totalMaps = getTotalOriginalData(orgNo, query, dates, idList);
            List<TreeVO> totalTree = BeanToolkit.instance().copyList(treeList, TreeVO.class);
            totalTree = totalTree.stream().filter(item -> Boolean.TRUE.equals(item.getSelectable())).toList();
            totalTree.forEach(item -> item.setType(null));

            DatatablePage totalDatatable = new DatatablePage();
            getDatatable(totalMaps, query, totalDatatable, totalTree, dates, totalRowData, showTarget);
            totalRowData = totalDatatable.getDatas().subList(2, totalDatatable.getDatas().size());
            totalRowData.forEach(rowData -> {
                rowData.put(PaisiConstants.PRODUCT_TECHNOLOGY_SHOW, rowData.get("name"));
                rowData.put(PaisiConstants.PRODUCT_TECHNOLOGY_COLUMN, rowData.get("code"));
                rowData.put("id", 0);
                rowData.put("code", "total");
                rowData.put("name", "合计");
                rowData.put(PaisiConstants.CAN_DRILL_DOWN, Boolean.FALSE);
                rowData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
                // 补零
                rowData.putIfAbsent("target", BigDecimal.ZERO);
            });

            // 总条数除以2
            datatable.setTotal(treeList.size() / 2);
        } else {
            // 有数据的政策ID
            Set<Long> hasDataSet = new HashSet<>();

            maps.forEach(map -> hasDataSet.add((Long) map.get("policy_id")));
            // 只保留有数据的树
            treeList = new ArrayList<>(treeList);
            treeList.removeIf(tree -> !hasDataSet.contains(tree.getId()));
            // 总页数
            datatable.setTotal(treeList.size());
        }

        // 构建报表数据
        getDatatable(maps, query, datatable, treeList, dates, totalRowData, showTarget);

        // 销售额除以一万
        formattingData(dates, datatable, query.getObjective());

        return datatable;
    }

    /**
     * 数据格式化处理
     * @param dates
     * @param datatable
     */
    private void formattingData(List<String> dates, DatatablePage datatable, Boolean objective) {
        List<String> allDataColumns = BeanToolkit.instance().copyList(dates, String.class);
        allDataColumns.add("total");
        allDataColumns.add("target");
        allDataColumns.add("diff");
        datatable.getDatas().forEach(obj -> {
            RowData rowData = (RowData) obj;
            for (String dataColumn : allDataColumns) {
                if (rowData.get(dataColumn) != null) {
                    // 给原值
                    if ("diff".equals(dataColumn)) {
                        rowData.put("diffNum", rowData.get(dataColumn));
                    }

                    if (PaisiConstants.SALES_AMOUNT.equals(rowData.get(PaisiConstants.ROW_TYPE))) {
                        rowData.put(dataColumn, ((BigDecimal) rowData.get(dataColumn)).divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP));
                    } else if (PaisiConstants.CUSTOMER_PROPORTION.equals(rowData.get(PaisiConstants.ROW_TYPE))
                            || PaisiConstants.SALES_PROPORTION.equals(rowData.get(PaisiConstants.ROW_TYPE))) {
                        if (objective !=  null && !objective) {
                            rowData.put(dataColumn, ((BigDecimal) rowData.get(dataColumn)).setScale(2, RoundingMode.HALF_UP) + "%");
                        } else {
                            rowData.put(dataColumn, ((BigDecimal) rowData.get(dataColumn)).setScale(2, RoundingMode.HALF_UP));

                        }
                    }
                }
            }
        });
    }

    // 生成固定表头
    private List<Title> getTitles(List<String> dates, PolicyEvolveDatatableQuery query, DictVO dict, boolean showTarget, boolean exportable) {
        // 实绩数据
        List<Title> titles;
        if (query.getDateType().equals(DateType.YEAR)) {
            titles = new ArrayList<>();
            dates.forEach(date -> {
                titles.add(Title.of(date, date + "年实绩"));
            });
        } else {
            titles = ETLUtils.getTitles(dates, query.getDateType().getValue());
        }

        List<Title> prefixTitles = new ArrayList<>();
        prefixTitles.add(Title.of("name", dict.getRemark()));
        // 新老商品方针
        if (PolicyEvolveType.PRODUCT_FEATURE.getValue().equals(query.getType())) {
            prefixTitles.add(Title.of(PaisiConstants.PRODUCT_TECHNOLOGY_SHOW, PaisiConstants.PRODUCT_TECHNOLOGY_NAME));
        }
        // 导出时不折叠
        if (exportable) {
            prefixTitles.add(Title.of(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.CATEGORY_NAME + "1"));
            prefixTitles.add(Title.of(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.CATEGORY_NAME + "2"));
        } else {
            Title category = Title.of(PaisiConstants.CATEGORY_COLUMN, PaisiConstants.CATEGORY_NAME);
            List<Title> children = new ArrayList<>();
            children.add(Title.of(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.CATEGORY_NAME + "1"));
            children.add(Title.of(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.CATEGORY_NAME + "2"));
            category.setChildren(children);
            prefixTitles.add(category);
        }

        // 插入最前面
        titles.addAll(0, prefixTitles);

        // 最后几列
        if (query.getObjective()) {
            titles.add(Title.of("target", query.getYear() + "年目标"));
        } else {
            titles.add(Title.of("total", "合计"));
            if (showTarget) {
                titles.add(Title.of("target", "目标"));
                titles.add(Title.of("diff", "差异"));
            }
        }
        return titles;
    }

    /**
     * 查询doris数据库
     *
     * @param orgNo
     * @param query
     * @param dates
     * @param idList
     * @return
     */
    private List<Map> getOriginalData(String orgNo, PolicyEvolveDatatableQuery query, List<String> dates, List<Long> idList) {
        String selectSql;

        switch (query.getType()) {
            case PaisiConstants.CORE_MARKET_POLICY:
                // 部门bu
                if (query.getDateType().equals(DateType.YEAR)) {
                    selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResDeptSalesByYear.sql");
                } else {
                    selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResDeptSalesByIds.sql");
                }
                break;
            case PaisiConstants.INDUSTRY_RESOURCES_POLICY:
            case PaisiConstants.CUSTOMER_LEVEL_POLICY:
            case PaisiConstants.CUSTOMER_FEATURES_POLICY:
                // 顾客
                if (query.getDateType().equals(DateType.YEAR)) {
                    selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyCustomerSalesByYear.sql");
                } else {
                    selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyCustomerSalesByIds.sql");
                }
                break;
            case PaisiConstants.PRODUCT_CATEGORY_POLICY:
            case PaisiConstants.PRODUCT_FEATURE_POLICY:
                // 商品
                if (query.getDateType().equals(DateType.YEAR)) {
                    selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyProductSalesByYear.sql");
                } else {
                    selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyProductSalesByIds.sql");
                }
                break;
            default:
                selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyProductSalesByIds.sql");
        }

        return getDataMaps(orgNo, query, dates, idList, selectSql);
    }


    private List<Map> getTotalOriginalData(String orgNo, PolicyEvolveDatatableQuery query, List<String> dates, List<Long> idList) {
        String selectSql;
        // 商品
        if (query.getDateType().equals(DateType.YEAR)) {
            selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyProductFeatureSalesByYear.sql");
        } else {
            selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyProductFeatureSalesByIds.sql");
        }

        return getDataMaps(orgNo, query, dates, idList, selectSql);
    }

    private List<Map> getDataMaps(String orgNo, PolicyEvolveDatatableQuery query, List<String> dates, List<Long> idList, String selectSql) {
        // 如果idList为空，直接返回空列表，避免查询所有数据
        if (idList == null || idList.isEmpty()) {
            return new ArrayList<>();
        }

        // 将idList转换为逗号分隔的字符串
        String idListStr = idList.stream().map(String::valueOf).collect(Collectors.joining(","));
        // 替换SQL中的占位符
        selectSql = selectSql.replace("{policyIds}", idListStr);

        List<Map> maps;
        // 通过月数据group by
        if (query.getDateType().equals(DateType.YEAR)) {
            maps = jdbcService.selectList(selectSql, new Object[]{
                    orgNo,
                    DateType.MONTH.getValue(),
                    query.getType(),
                    dates.getFirst() + "-01",
                    dates.getLast() + "-12"
            });
        } else {
            maps = jdbcService.selectList(selectSql, new Object[]{
                    orgNo,
                    query.getDateType().getValue(),
                    query.getType(),
                    dates.getFirst(),
                    dates.getLast()}
            );
        }
        return maps;
    }


    private void getDatatable(List<Map> maps, PolicyEvolveDatatableQuery query, DatatablePage datatable, List<TreeVO> treeList,
                                          List<String> dates, List<RowData> totalRowData, boolean showTarget) {

        // 每一列数据
        Map<Long, Map<String, RowData>> mainRowDateMap = new LinkedHashMap<>();
        // 左侧栏归类
        treeList.forEach(tree -> createPolicyRow(tree, mainRowDateMap, query.getObjective(), query.getYear()));

        // 行合计
        Map<String, BigDecimal> totalRowMap = new HashMap<>();
        // 列合计
        Map<String, BigDecimal> totalDateMap = new HashMap<>();

        // 数据填入，计算合计
        maps.forEach(map -> {
            Long id = (Long) map.get("policy_id");
            String date = map.get("date").toString();
            String productTechnology = map.get("product_technology") != null ? map.get("product_technology").toString() : "";
            if (productTechnology.equals(ProductTechnologyType.EXPAND.getValue())
                    || productTechnology.equals(ProductTechnologyType.EXTEND.getValue())) {
                id = id + ADD_ID_NUM;
            }
            if (mainRowDateMap.containsKey(id)) {

                Map<String, RowData> rowDataMap = mainRowDateMap.get(id);
                if (rowDataMap.containsKey(PaisiConstants.SALES_AMOUNT)) {
                    RowData rowData = rowDataMap.get(PaisiConstants.SALES_AMOUNT);
                    rowData.put(date, map.get(PaisiConstants.SALES_COLUMN));
                    BigDecimal sales = new BigDecimal(map.get(PaisiConstants.SALES_COLUMN).toString());
                    // 行合计
                    setTotalMap(totalRowMap, id + SPLIT_KEY + PaisiConstants.SALES_AMOUNT, sales);
                    // 列合计
                    setTotalMap(totalDateMap, date + SPLIT_KEY + PaisiConstants.SALES_AMOUNT, sales);
                }
                if (rowDataMap.containsKey(PaisiConstants.CUSTOMER_COUNT)) {
                    RowData rowData = rowDataMap.get(PaisiConstants.CUSTOMER_COUNT);
                    rowData.put(date, map.get(PaisiConstants.CUSTOMER_NUM_COLUMN));
                    BigDecimal customers = new BigDecimal(map.get(PaisiConstants.CUSTOMER_NUM_COLUMN).toString());
                    // 行合计
                    setTotalMap(totalRowMap, id + SPLIT_KEY + PaisiConstants.CUSTOMER_COUNT, customers);
                    // 列合计
                    setTotalMap(totalDateMap, date + SPLIT_KEY + PaisiConstants.CUSTOMER_COUNT, customers);
                }
            }
        });


        // 分页处理
        if (query.getPageNum() <= 0) {
            query.setPageNum(1);
        }
        // 如果是新老商品，则页面大小翻倍
        if (PolicyEvolveType.PRODUCT_FEATURE.getValue().equals(query.getType())) {
            query.setPageSize(query.getPageSize() * 2);
        }
        List<Long> idList = treeList.stream().map(TreeVO::getId).toList();
        List<Long> filterIds;
        if (query.getPageSize() * (query.getPageNum() - 1) > idList.size()) {
            filterIds = new ArrayList<>();
        } else {
            filterIds = idList.subList(query.getPageSize() * (query.getPageNum() - 1), Math.min(idList.size(), query.getPageSize() * query.getPageNum())).stream().toList();
        }

        AnnualPolicyGoalSummaryVO summary;
        Map<Long, AnnualPolicyGoalVO> targetMap = new HashMap<>();
        if (showTarget) {
            // 插入目标数据
            AnnualPolicyGoalTargetQry annualPolicyGoalTargetQry = new AnnualPolicyGoalTargetQry()
                    .setYear(query.getYear())
                    .setType(query.getType());
            if (query.getYear() == null) {
                annualPolicyGoalTargetQry.setYear(query.getEndDate().substring(0, 4));
            }
            // 新老商品不需要过滤固定ids
            if (idList.size() > 100) {
                annualPolicyGoalTargetQry.setParentId(query.getPolicyId() == null ? 0L : query.getPolicyId());
            } else if (!PolicyEvolveType.PRODUCT_FEATURE.getValue().equals(query.getType())) {
                annualPolicyGoalTargetQry.setPolicyIds(idList);
            }
            AnnualPolicyGoalTargetVO goalTarget;
            // 没数就不需要请求目标了
            if (idList.isEmpty()) {
                goalTarget = null;
            } else {
                Response<AnnualPolicyGoalTargetVO> targetListRes = annualPolicyGoalRemoteService.selectTargetList(annualPolicyGoalTargetQry);
                goalTarget = targetListRes.get();
            }
            if (goalTarget != null) {
                goalTarget.getRecords().forEach(item -> targetMap.put(item.getPolicyId(), item));
                if (goalTarget.getSummaries() != null && !goalTarget.getSummaries().isEmpty()) {
                    summary = goalTarget.getSummaries().getFirst();
                } else {
                    summary = new AnnualPolicyGoalSummaryVO();
                }
            } else {
                summary = new AnnualPolicyGoalSummaryVO();
            }
        } else {
            summary = new AnnualPolicyGoalSummaryVO();
        }

        List<RowData> result = new ArrayList<>();

        // 第一行合计行
        Map<String, RowData> totalResultMap = createTotalRow(totalDateMap, result, summary);
        // 自定义第一行合计
        if (StringUtil.isNotEmpty(totalRowData)) {
            result.clear();
            result.addAll(totalRowData);
        }

        // 平铺数据
        mainRowDateMap.forEach((id, rowDataMap) -> {
            if (!filterIds.contains(id)) {
                return;
            }
            rowDataMap.forEach((key, rowData) -> {
                result.add(rowData);

                if (totalRowMap.containsKey(id + SPLIT_KEY + key)) {
                    rowData.put("total", totalRowMap.get(id + SPLIT_KEY + key));
                }

                // 填入占比技术
                if (key.equals(PaisiConstants.CUSTOMER_PROPORTION)
                        && rowDataMap.containsKey(PaisiConstants.CUSTOMER_COUNT)) {
                    this.setProportionDataRow(rowDataMap, dates, totalDateMap, rowData, totalResultMap, PaisiConstants.CUSTOMER_COUNT);
                }
                if (key.equals(PaisiConstants.SALES_PROPORTION)
                        && rowDataMap.containsKey(PaisiConstants.SALES_AMOUNT)) {
                    this.setProportionDataRow(rowDataMap, dates, totalDateMap, rowData, totalResultMap, PaisiConstants.SALES_AMOUNT);
                }

                // 插入目标
                BigDecimal target = null;
                // 新老商品特殊逻辑目标合计
                if (PolicyEvolveType.PRODUCT_FEATURE.getValue().equals(query.getType()) && totalRowData.isEmpty()) {
                    if ("new".equals(rowData.get("code"))) {
                        target = switch (key) {
                            case PaisiConstants.CUSTOMER_COUNT ->
                                    summary.getNewProductCustomerCount() != null ? new BigDecimal(summary.getNewProductCustomerCount()) : null;
                            case PaisiConstants.SALES_AMOUNT -> summary.getNewProductSalesAmount();
                            case PaisiConstants.SALES_PROPORTION -> summary.getNewProductSalesRatio();
                            case PaisiConstants.CUSTOMER_PROPORTION -> summary.getNewProductCustomerRatio();
                            default -> target;
                        };
                    } else {
                        target = switch (key) {
                            case PaisiConstants.CUSTOMER_COUNT ->
                                    summary.getOldProductCustomerCount() != null ? new BigDecimal(summary.getOldProductCustomerCount()) : null;
                            case PaisiConstants.SALES_AMOUNT -> summary.getOldProductSalesAmount();
                            case PaisiConstants.SALES_PROPORTION -> summary.getOldProductSalesRatio();
                            case PaisiConstants.CUSTOMER_PROPORTION -> summary.getOldProductCustomerRatio();
                            default -> target;
                        };
                    }
                } else {
                    // 正常模式
                    if (targetMap.containsKey(id)) {
                        switch (key) {
                            case PaisiConstants.CUSTOMER_COUNT -> {
                                Integer customerCount = targetMap.get(id).getCustomerCount();
                                target = customerCount != null ? new BigDecimal(customerCount) : null;
                            }
                            case PaisiConstants.SALES_AMOUNT -> target = targetMap.get(id).getSalesAmount();
                            case PaisiConstants.SALES_PROPORTION -> target = targetMap.get(id).getSalesRatio();
                            case PaisiConstants.CUSTOMER_PROPORTION -> target = targetMap.get(id).getCustomerRatio();
                        }
                    }
                }
                rowData.put("target", target);
                BigDecimal total = rowData.containsKey("total") ? (BigDecimal) rowData.get("total") : null;
                if (total != null && target != null) {
                    BigDecimal diff = total.subtract(target);
                    rowData.put("diff", diff);
//                        rowData.put("color", diff.compareTo(BigDecimal.ZERO) < 0 ? "red" : "green");
                }

            });
        });

        // 还原ID减
//        result.stream().filter(item-> item.get("changeable") != null && item.get("changeable").equals(false) && item.get("id") != null && (Long)item.get("id") != 0L)
//                .forEach(rowData -> {
//                    rowData.put("id", (Long)rowData.get("id") - ADD_ID_NUM);
//                });
        // todo 查询目标值，计算差异

        datatable.setDatas(result);

    }

    /**
     * 设置占比数据
     */
    private void setProportionDataRow(Map<String, RowData> rowDataMap, List<String> dates, Map<String, BigDecimal> totalDateMap,
                                      RowData rowData, Map<String, RowData> totalResultMap, String column) {

        RowData customerRowData = rowDataMap.get(column);
        for (String date : dates) {
            if (customerRowData.containsKey(date)) {
                BigDecimal total = totalDateMap.get(date + SPLIT_KEY + column);
                BigDecimal value = new BigDecimal(customerRowData.get(date).toString());
                if (total.compareTo(BigDecimal.ZERO) == 0) {
                    rowData.put(date, BigDecimal.ZERO);
                } else {
                    // 占比技术， 值/总数 %
                    rowData.put(date, value.multiply(new BigDecimal(100)).divide(total, 2, RoundingMode.HALF_UP));
                }
            }
        }

        // 合计占比
        Object totalObj = totalResultMap.get(column).get("total");
        Object valueObj = customerRowData.get("total");
        if (totalObj != null && valueObj != null && ((BigDecimal) totalObj).compareTo(BigDecimal.ZERO) != 0) {
            rowData.put("total", ((BigDecimal) valueObj).multiply(new BigDecimal(100)).divide(((BigDecimal) totalObj), 2, RoundingMode.HALF_UP));
        }

    }

    /**
     * 合计数据相加
     *
     * @param totatMap
     * @param key
     * @param value
     */
    private void setTotalMap(Map<String, BigDecimal> totatMap, String key, BigDecimal value) {
        if (!totatMap.containsKey(key)) {
            totatMap.put(key, BigDecimal.ZERO);
        }
        totatMap.put(key, totatMap.get(key).add(value));
    }

    /**
     * 获取数据左侧栏主体
     */
    public List<TreeVO> getRowInfoTrees(Long policyId, String type, Boolean objective) {
        List<TreeVO> treeList;

        if (!type.equals(PolicyEvolveType.CORE_MARKET.getValue())) {
            // 政策信息列表
            Response<List<PolicyDetailVO>> policyListRes = policyDetailRemoteService.selectListForChild(new PolicyDetailListQry()
                    .setType(type)
                    .setParentId(policyId != null ? policyId : 0L)
                    .setStatus(1));
            List<PolicyDetailVO> policyDetailList = policyListRes.get();
            // 如果是目标，最多只能钻取到2级
            if (policyDetailList != null && objective) {
                policyDetailList = policyDetailList.stream().filter(item -> item.getLevel() <= 2).toList();
            }

            if (StringUtil.isEmpty(policyDetailList) && policyId != null) {
                // 如果没有下级，就返回他自己
                policyDetailList = policyDetailRemoteService.selectList(new PolicyDetailListQry()
                        .setType(type)
                        .setIds(Collections.singletonList(policyId))
                        .setStatus(1)).get();
            }
            if (policyDetailList == null) {
                policyDetailList = new ArrayList<>();
            }

            treeList = policyDetailList.stream().flatMap(item -> setTree(item).stream()).toList();
        } else {
            Response<List<TreeVO>> deptTreeRes = deptRemoteService.selectManyMKDeptTreeByDataScope(new DeptTreeQry());
            if (deptTreeRes.get() == null) {
                treeList = new ArrayList<>();
            } else {
                treeList = deptTreeRes.get();
                treeList.forEach(item -> item.setType(null));
            }
        }
        return treeList;
    }

    /**
     * 政策转树状结构
     *
     * @param policyDetail
     * @return
     */
    private List<TreeVO> setTree(PolicyDetailVO policyDetail) {
        List<TreeVO> treeList = new ArrayList<>();
        TreeVO tree = new TreeVO()
                .setId(policyDetail.getId())
                .setLabel(policyDetail.getName())
                .setCode(policyDetail.getCode())
                .setParentId(policyDetail.getParentId())
                .setExtId(policyDetail.getLevel().toString())
                .setChildren(policyDetail.getChildren().stream().flatMap(item -> setTree(item).stream()).toList());
        if (policyDetail.getType().equals(PolicyEvolveType.PRODUCT_FEATURE.getValue())
                && policyDetail.getCode().equals("old")) {
            tree.setType(ProductTechnologyType.SPECIALIZE.getValue());
            tree.setSelectable(true);
            treeList.add(tree);

            TreeVO tree2 = BeanToolkit.instance().copy(tree, TreeVO.class);
            tree2.setId(tree.getId() + ADD_ID_NUM);
            tree2.setSelectable(false);
            tree2.setType(ProductTechnologyType.EXPAND.getValue());
            treeList.add(tree2);
        } else if (policyDetail.getType().equals(PolicyEvolveType.PRODUCT_FEATURE.getValue())
                && policyDetail.getCode().equals("new")) {
            tree.setType(ProductTechnologyType.ENRICH.getValue());
            tree.setSelectable(true);
            treeList.add(tree);

            TreeVO tree2 = BeanToolkit.instance().copy(tree, TreeVO.class);
            tree2.setId(tree.getId() + ADD_ID_NUM);
            tree2.setSelectable(false);
            tree2.setType(ProductTechnologyType.EXTEND.getValue());
            treeList.add(tree2);
        } else {
            treeList.add(tree);
        }

        return treeList;
    }

    /**
     * 创建合计行
     *
     * @param totalDateMap
     * @param rowList
     */

    private Map<String, RowData> createTotalRow(Map<String, BigDecimal> totalDateMap, List<RowData> rowList, AnnualPolicyGoalSummaryVO summary) {

        Map<String, RowData> totalRowMap = new LinkedHashMap<>();
        // 客数
        RowData customerNumData = getTotalBaseRow();
        customerNumData.put(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.CUSTOMER_NUM_NAME);
        customerNumData.put(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.NUM_NAME);
        customerNumData.put(PaisiConstants.ROW_TYPE, PaisiConstants.CUSTOMER_COUNT);
        customerNumData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
        customerNumData.put("uniqueCode", "0" + SPLIT_KEY + PaisiConstants.CUSTOMER_COUNT);
        customerNumData.put("target", summary.getTotalCustomerCount() == null ? BigDecimal.ZERO : summary.getTotalCustomerCount());


        // 销售额数量
        RowData saleAmountData = getTotalBaseRow();
        saleAmountData.put(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.SALES_NAME + "(万)");
        saleAmountData.put(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.NUM_NAME);
        saleAmountData.put(PaisiConstants.ROW_TYPE, PaisiConstants.SALES_AMOUNT);
        saleAmountData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
        saleAmountData.put("uniqueCode", "0" + SPLIT_KEY + PaisiConstants.SALES_AMOUNT);
        saleAmountData.put("target", summary.getTotalSalesAmount() == null ? BigDecimal.ZERO : summary.getTotalSalesAmount()) ;

        // 写入合计数据
        BigDecimal saleAmountTotal = BigDecimal.ZERO;
        BigDecimal customerNumTotal = BigDecimal.ZERO;
        for (String key : totalDateMap.keySet()) {
            BigDecimal value = totalDateMap.get(key);
            String[] strList = key.split(SPLIT_KEY);
            if (strList.length == 2) {
                if (strList[1].equals(PaisiConstants.SALES_AMOUNT)) {
                    saleAmountData.put(strList[0], value);
                    saleAmountTotal = saleAmountTotal.add(value);
                } else if (strList[1].equals(PaisiConstants.CUSTOMER_COUNT)) {
                    customerNumData.put(strList[0], value);
                    customerNumTotal = customerNumTotal.add(value);
                }
            }
        }
        if (customerNumTotal.compareTo(BigDecimal.ZERO) != 0) {
            customerNumData.put("total", customerNumTotal);
            if (summary.getTotalCustomerCount() != null) {
                customerNumData.put("diff", customerNumTotal.subtract(new BigDecimal(summary.getTotalCustomerCount())));
//            customerNumData.put("color", diff.compareTo(BigDecimal.ZERO) < 0 ? "red" : "green");
            }
        }
        if (saleAmountTotal.compareTo(BigDecimal.ZERO) != 0) {
            saleAmountData.put("total", saleAmountTotal);
            if (summary.getTotalSalesAmount() != null) {
                saleAmountData.put("diff", saleAmountTotal.subtract(summary.getTotalSalesAmount()));
            }
        }

        totalRowMap.put(PaisiConstants.CUSTOMER_COUNT, customerNumData);
        totalRowMap.put(PaisiConstants.SALES_AMOUNT, saleAmountData);
        // 放到最上边
        rowList.addAll(0, totalRowMap.values());
        return totalRowMap;
    }

    // 基础列数据
    private RowData getTotalBaseRow() {
        RowData rowData = new RowData();
        rowData.put("id", 0);
        rowData.put("code", "total");
        rowData.put("name", "合计");
        rowData.put(PaisiConstants.CAN_DRILL_DOWN, Boolean.FALSE);
        rowData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
        return rowData;
    }

    /**
     * 构建每个政策的左侧表头数据
     *
     * @param tree
     * @param mainRowDateMap
     */
    private void createPolicyRow(TreeVO tree, Map<Long, Map<String, RowData>> mainRowDateMap, Boolean objective, String year) {

        // 客数数量
        Map<String, RowData> rowDataMap = new LinkedHashMap<>();
        RowData customerNumData = getBaseRowData(tree, objective);
        customerNumData.put(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.CUSTOMER_NUM_NAME);
        customerNumData.put(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.NUM_NAME);
        customerNumData.put(PaisiConstants.ROW_TYPE, PaisiConstants.CUSTOMER_COUNT);
        customerNumData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.TRUE);
        if (tree.getType() != null) {
            customerNumData.put(PaisiConstants.PRODUCT_TECHNOLOGY_COLUMN, tree.getType());
            customerNumData.put(PaisiConstants.PRODUCT_TECHNOLOGY_SHOW, ProductTechnologyType.getProductTechnologyType(tree.getType()).getDesc());
            customerNumData.put("changeable", tree.getSelectable());
        }
        customerNumData.put("uniqueCode", tree.getId() + SPLIT_KEY + PaisiConstants.CUSTOMER_COUNT);
        rowDataMap.put(PaisiConstants.CUSTOMER_COUNT, customerNumData);
        // 目标不展示
        if (!objective) {
            // 客数占比
            RowData customerNumProportionData = getBaseRowData(tree, objective);
            customerNumProportionData.put(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.CUSTOMER_NUM_NAME);
            customerNumProportionData.put(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.PROPORTION_NAME);
            customerNumProportionData.put(PaisiConstants.ROW_TYPE, PaisiConstants.CUSTOMER_PROPORTION);
            customerNumProportionData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
            if (tree.getType() != null) {
                customerNumProportionData.put(PaisiConstants.PRODUCT_TECHNOLOGY_COLUMN, tree.getType());
                customerNumProportionData.put(PaisiConstants.PRODUCT_TECHNOLOGY_SHOW, ProductTechnologyType.getProductTechnologyType(tree.getType()).getDesc());
                customerNumProportionData.put("changeable", tree.getSelectable());
            }
            customerNumProportionData.put("uniqueCode", tree.getId() + SPLIT_KEY + PaisiConstants.CUSTOMER_PROPORTION);
            rowDataMap.put(PaisiConstants.CUSTOMER_PROPORTION, customerNumProportionData);
        }
        // 销售额数量
        RowData saleAmountData = getBaseRowData(tree, objective);
        saleAmountData.put(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.SALES_NAME + "(万)");
        saleAmountData.put(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.NUM_NAME);
        saleAmountData.put(PaisiConstants.ROW_TYPE, PaisiConstants.SALES_AMOUNT);
        saleAmountData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.TRUE);
        if (tree.getType() != null) {
            saleAmountData.put(PaisiConstants.PRODUCT_TECHNOLOGY_COLUMN, tree.getType());
            saleAmountData.put(PaisiConstants.PRODUCT_TECHNOLOGY_SHOW, ProductTechnologyType.getProductTechnologyType(tree.getType()).getDesc());
            saleAmountData.put("changeable", tree.getSelectable());
        }
        saleAmountData.put("uniqueCode", tree.getId() + SPLIT_KEY + PaisiConstants.SALES_AMOUNT);
        rowDataMap.put(PaisiConstants.SALES_AMOUNT, saleAmountData);
        // 销售额数量占比
        RowData saleNumProportionData = getBaseRowData(tree, objective);
        saleNumProportionData.put(PaisiConstants.CATEGORY_COLUMN + "1", PaisiConstants.SALES_NAME + "(万)");
        saleNumProportionData.put(PaisiConstants.CATEGORY_COLUMN + "2", PaisiConstants.PROPORTION_NAME);
        saleNumProportionData.put(PaisiConstants.ROW_TYPE, PaisiConstants.SALES_PROPORTION);
        saleNumProportionData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
        if (tree.getType() != null) {
            saleNumProportionData.put(PaisiConstants.PRODUCT_TECHNOLOGY_COLUMN, tree.getType());
            saleNumProportionData.put(PaisiConstants.PRODUCT_TECHNOLOGY_SHOW, ProductTechnologyType.getProductTechnologyType(tree.getType()).getDesc());
            saleNumProportionData.put("changeable", tree.getSelectable());
        }
        saleNumProportionData.put("uniqueCode", tree.getId() + SPLIT_KEY + PaisiConstants.SALES_PROPORTION);
        rowDataMap.put(PaisiConstants.SALES_PROPORTION, saleNumProportionData);
        mainRowDateMap.put(tree.getId(), rowDataMap);

        // 获取当前年份
        String currentYear = com.stm.framework.core.util.DateUtils.parseDateToStr(new Date(), "yyyy");
        // 判断年份是否大于当前年
        if (year.compareTo(currentYear) < 0) {
            // 历史年不给填
            customerNumData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
            saleAmountData.put(PaisiConstants.EDITABLE_COLUMN, Boolean.FALSE);
        }
    }

    private RowData getBaseRowData(TreeVO tree, Boolean objective) {
        RowData rowData = new RowData();
        rowData.put("id", tree.getId());
        rowData.put("code", tree.getCode());
        rowData.put("name", tree.getLabel());
        // 是否有子集
        if (tree.getChildren() != null && !tree.getChildren().isEmpty()) {
            // 目标填写只能钻取一级
            if (Boolean.TRUE.equals(objective)) {
                if ("1".equals(tree.getExtId())) {
                    rowData.put(PaisiConstants.CAN_DRILL_DOWN, Boolean.TRUE);
                } else {
                    rowData.put(PaisiConstants.CAN_DRILL_DOWN, Boolean.FALSE);
                }
            } else {
                rowData.put(PaisiConstants.CAN_DRILL_DOWN, Boolean.TRUE);
            }
        } else {
            rowData.put(PaisiConstants.CAN_DRILL_DOWN, Boolean.FALSE);
        }
        return rowData;
    }


    @Override
    public String getReportName() {
        return "经营过程实绩推移列表";
    }

    @Override
    public boolean syncExport(DatatablePage page) {
        return false;
    }
}
